# -*-coding:utf-8-*-
# 将序列转换为二进制形式

from typing import Union, List
import  numpy as np

def BLOSUM62(
        sequenece: str,
        order: Union[str, None] = None
) -> List:
    '''
    计算序列的二进制形式
    :param sequenece:string 序列
    :param order: Union[str,None] 默认"ACDEFGHIKLMNPQRSTVWY-"
    :return: List 返回len(sequenece)*21的维度
    '''

    if order == None:
        order = "ACDEFGHIKLMNPQRSTVWY-"

    blosum62 = {
        'A': [4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3, -2, 0],  # A
        'R': [-1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3, -2, -3],  # R
        'N': [-2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2, -3],  # N
        'D': [-2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4, -3, -3],  # D
        'C': [0, -3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1, -2, -2, -1],  # C
        'Q': [-1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1, -2],  # Q
        'E': [-1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2, -2],  # E
        'G': [0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2, -3, -3],  # G
        'H': [-2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2, 2, -3],  # H
        'I': [-1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3, -1, 3],  # I
        'L': [-1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2, -1, 1],  # L
        'K': [-1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3, -2, -2],  # K
        'M': [-1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1, -1, 1],  # M
        'F': [-2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1, 3, -1],  # F
        'P': [-1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1, -4, -3, -2],  # P
        'S': [1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2, -2],  # S
        'T': [0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2, -2, 0],  # T
        'W': [-3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2, 11, 2, -3],  # W
        'Y': [-2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2, 2, 7, -1],  # Y
        'V': [0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3, -1, 4],  # V
        '-': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # -
    }

    # encodings = []
    #
    # for i in sequenece:
    #     name, sequence = i[0], i[1]
    #     code = [name]
    #     for aa in sequence:
    #         code = code + blosum62[aa]
    #     encodings.append(code)
    # return encodings

    # aadict = {}
    # for i, j in enumerate(order):
    #     aadict[j] = ['0'] * i + ['1'] + ['0'] * (len(order) - i - 1)

    encodings = []
    for i in sequenece:
        if i in blosum62:
            encodings = encodings + blosum62[i]
        else:
            encodings = encodings + blosum62['-']

    return encodings

def one_BLOSUM62(data, windows=15):
    data = data
    length = len(data)
    data_X = np.zeros((length, (2*windows+1), 20))
    data_Y = []
    for i in range(length):
        x = data[i].split(',')
        data_Y.append(int(x[4]))
        aaindex = np.array(BLOSUM62(x[5]))
        # print(x[5])
        # print(aaindex.shape)
        # print(aaindex.reshape((2*windows+1),21))
        data_X[i] = aaindex.reshape((2*windows+1),20)
    data_Y = np.array(data_Y)
    return data_X, data_Y

if __name__ == '__main__':
    f_r_train = open('hit-40/totalsum.csv')
    train_data = f_r_train.readlines()
    result = one_BLOSUM62(train_data)
    print(result)